package home.projects.misc;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.File;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

// http://www.youtube.com/watch?v=txqiwrbYGrs&feature=related
public class ASGeneratorTest {

   public static void main(final String[] args) {
      ASGenerator asGen = new ASGenerator();
//      asGen.set ("com.majescomastek.vo");
//      asGen.set_javaPkg("com.majescomastek.sbs.ws.valueobject");
//      asGen.set_source(new File("C:\\Test"));
//      asGen.set_target(new File("C:\\Test"));
      asGen.generate();
   }
}

/**
 * Restrictions:
 *    - can only traverse a given package, no nested traversals
 *    
 *    
 * @author SANJAY
 *
 */
class ASGenerator {

   private String targetPkg;

   private String sourcePkg;
   
   private File sourcePath;

   private File targetPath;
   
   private Template template;
   
   public ASGenerator() {
      try {
         Configuration cfg = new Configuration();
         cfg.setDirectoryForTemplateLoading(
                 new File("E:\\rnd\\eclipse-workspace\\JTest\\src\\home\\projects\\templates"));
         cfg.setObjectWrapper(new DefaultObjectWrapper());
         template = cfg.getTemplate("my.ftl");
      } catch(Exception e) {
         e.printStackTrace();
      }
   }
   
   public void generate() {
      try {
         URLClassLoader loader = URLClassLoader.newInstance(new URL[] { sourcePath
               .toURL() });
         String[] fileNames = new File(sourcePath, sourcePkg.replace('.', '/')).list(new ClassFileFilter());
         for(String fileName : fileNames) {
            Class<?> c = loader.loadClass(sourcePkg + "." + fileName.replaceAll("\\.class", ""));
            processClass(c);
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   
   private void processClass(Class klass) throws Exception {
      File f = new File(targetPath, klass.getSimpleName() + ".as");
      PrintWriter out = new PrintWriter(f);

      Map root = new HashMap();
      root.put("asPackage", targetPkg);
      root.put("javaPackage", sourcePkg);
      root.put("class", klass);
      root.put("parentClass", klass.getSuperclass());
      root.put("fields", Arrays.asList(klass.getDeclaredFields()));
      template.process(root, out);
      out.flush();
      out.close();
   }

   public void setTargetPkg(String targetPkg) {
      this.targetPkg = targetPkg;
   }

   public void setSourcePkg(String sourcePkg) {
      this.sourcePkg = sourcePkg;
   }

   public void setSourcePath(File sourcePath) {
      this.sourcePath = sourcePath;
   }

   public void setTargetPath(File targetPath) {
      this.targetPath = targetPath;
   }

   public void setTemplate(Template template) {
      this.template = template;
   }
   
}

class ClassFileFilter implements FilenameFilter {

   public boolean accept(File dir, String name) {
//      return(name.endsWith(".class"));
      return(name.equals("PolicyEntity.class"));
   }
   
}

interface TypeMapper {
   String mapType(String type);
}

class JavaToAsTypeMapper implements TypeMapper {

   public String mapType(String type) {
      if("List".equals(type)) {
         return "ArrayCollection";
      } else {
         return type;
      }
   }

}
